home *** CD-ROM | disk | FTP | other *** search
/ Aminet 21 / Aminet 21 (1997)(GTI - Schatztruhe)[!][Oct 1997].iso / Aminet / gfx / show / gs503_data.lha / Ghostscript / data / gs_cidfn.ps < prev    next >
Text File  |  1997-08-14  |  13KB  |  429 lines

  1. %    Copyright (C) 1995, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % ProcSet for implementing CIDFont and CIDMap resources.
  16. % When this is run, systemdict is still writable.
  17.  
  18. % ---------------- Defining CIDFont resources ---------------- %
  19.  
  20. % Define a CIDFont resource.  This is the defineresource implementation for
  21. % the CIDFont resource category.
  22.  
  23. /.definecidfont [
  24.  
  25. % CIDFontType 0
  26. { dup /FontMatrix known not
  27.    { dup /FontMatrix [0.001 0 0 0.001 0 0] put
  28.      dup /FDArray get
  29.       { /FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop }
  30.      forall
  31.    }
  32.   if
  33.   dup /FDArray get mark exch
  34.    {        % Add pro forma entries
  35.      dup /FontType 1 put
  36.      dup /CharStrings 10 dict put
  37.      dup /Encoding [] put
  38.         % Create a dummy Subrs array now.
  39.      dup /Private get dup /SubrCount .knownget
  40.       { array 1 index /Subrs 3 -1 roll put }
  41.      if pop
  42.      dup /FontName .knownget not { () } if exch .buildfont1 exch pop
  43.    }
  44.   forall ] 1 index /FDepVector 3 -1 roll put
  45.   1 index exch .buildfont9 exch pop
  46. } bind
  47.  
  48. % CIDFontType 1
  49. { 1 index exch .buildfont10 exch pop
  50. } bind
  51.  
  52. % CIDFontType 2
  53. { 1 index exch .buildfont11 exch pop
  54. } bind
  55.  
  56. ] def
  57.  
  58. % ---------------- Reading CIDFontType 0 files ---------------- %
  59.  
  60. 30 dict begin
  61.  
  62. % We add the following entries to the CIDFont dictionary, in addition to
  63. % the ones documented by Adobe:
  64. %    ReadString - procedure for reading a string from the binary data
  65. %    SubrCache - dictionary for caching Subr arrays
  66. % For CIDFonts where we read the data from disk incrementally:
  67. %    DataOffset - starting position of data in file
  68. %    (if data are in hex) OffsetMap - map from logical data positions to
  69. %      physical positions in file
  70.  
  71. /StartData        % <(Binary)|(Hex)> <datalength> StartData -
  72.             %   (currentdict is CID font dict)
  73. {        % If we're loading a resource file, we can just save a
  74.         % pointer to the binary data and load it incrementally.
  75.         % Check for this by opening the resource file,
  76.         % positioning it to currentfile's position plus the
  77.         % data length, and checking for %%EndData.
  78.    mark
  79.     { currentfile fileposition
  80.       CIDFontName 100 string ResourceFileName (r) file
  81.        mark
  82.     {        % Stack: (Binary)|(Hex) length -mark- pos resfile
  83.             %   -mark-
  84.       5 index (Hex) eq
  85.        { 1 index 3 index setfileposition
  86.          1 index 5 index .skiphex
  87.             %**************** SKIP > AND WHITESPACE SOMEHOW
  88.        }
  89.        { 1 index 3 index 6 index add setfileposition
  90.        }
  91.       ifelse
  92.       1 index 9 string readstring pop (%%EndData) ne { stop } if
  93.     }
  94.        .internalstopped { cleartomark closefile stop } if
  95.        pop        % pop the mark
  96.     }
  97.    .internalstopped
  98.    {        % File is not positionable, load the data now.
  99.      cleartomark exch (Hex) eq
  100.       { { currentfile exch readhexstring pop } }
  101.       { { currentfile exch readstring pop } }
  102.      ifelse /ReadString exch def
  103.      dup 65535 le
  104.       { string ReadString
  105.       }
  106.       { mark exch
  107.      { dup 0 eq { pop exit } if
  108.        dup 65535 min dup string ReadString
  109.        3 1 roll sub
  110.      }
  111.     loop ]
  112.       }
  113.      ifelse
  114.      /GlyphData exch def
  115.      /.vmreadstring cvx
  116.    }
  117.    {        % File is positionable, just save a pointer.
  118.         % Stack: (Binary)|(Hex) length -mark- pos file
  119.      4 1 roll
  120.      /DataOffset exch def
  121.      pop /GlyphData exch def
  122.      exch (Hex) eq
  123.       {        % Hex data, build the offset map.
  124.     .buildoffsetmap
  125.     /.hexreadstring
  126.       }
  127.       {        % Binary data, just skip over it.
  128.     currentfile DataOffset GlyphData add setfileposition
  129.     /.binaryreadstring
  130.       }
  131.      ifelse cvx
  132.      2 packedarray cvx
  133.    }
  134.   ifelse /ReadString exch def
  135.   /SubrCache 10 dict def
  136.   CIDFontName currentdict /CIDFont defineresource pop
  137.   end            % CID font dict
  138.   end            % resource category dict
  139. } bind def
  140.  
  141. % Skip a given distance in an ASCIIHex encoded file.  We use this at
  142. % rendering time as well.
  143. /.skiphex        % <file> <count> .skiphex -
  144. { exch /ASCIIHexDecode filter dup 3 -1 roll () /SubFileDecode filter
  145.   dup flushfile closefile closefile
  146. } bind def
  147.  
  148. % Build the map from logical offsets to physical offsets in ASCIIHex
  149. % encoded data.
  150. /.buildoffsetmap
  151. { /OffsetMap GlyphData 256 idiv 8000 min array def
  152.   2 dict begin
  153.      /block GlyphData OffsetMap length idiv def
  154.      0 1 OffsetMap length 1 sub
  155.       { OffsetMap exch currentfile fileposition put
  156.     currentfile block .skiphex
  157.       }
  158.      for
  159.      GlyphData block mod dup 0 eq
  160.       { pop }
  161.       { currentfile exch .skiphex }
  162.      ifelse
  163.   end            % scratch dict
  164. } bind def
  165.  
  166. currentdict end
  167.  
  168. % ---------------- Rendering ---------------- %
  169.  
  170. % ------ Generic ------ %
  171.  
  172. % Read a string at a given offset in a "file" (binary file, ASCII hex file,
  173. % or GlyphData in RAM).
  174. /.binaryreadstring    % <pos> <string> <file> .binaryreadstring <string>
  175.  { dup 4 -1 roll DataOffset add setfileposition exch readstring pop
  176.  } bind def
  177. /.hexreadstring        % <pos> <string> <file> .hexreadstring <string>
  178. {        % Use the OffsetMap to get to the block of hex data,
  179.         % then skip to the correct position by reading.
  180.   GlyphData OffsetMap length idiv
  181.         % Stack: pos string file blocklen
  182.   3 index 1 index idiv OffsetMap exch get
  183.   2 index exch setfileposition
  184.         % Skip the next (pos % blocklen) hex bytes.
  185.   4 -1 roll exch mod 1 index exch .skiphex
  186.         % Stack: string file
  187.   exch readhexstring pop  
  188. } bind def
  189. /.vmreadstring        % <pos> <string> .vmreadstring <vmstring>
  190. { GlyphData .stringsreadstring
  191. } bind def
  192. /.stringsreadstring    % <pos> <string> <strings> .stringsreadstring
  193.             %   <vmstring>
  194. { dup type /stringtype eq
  195.    { 3 1 roll length getinterval
  196.    }
  197.    {  {        % Stack: pos string glyphdata
  198.     dup 0 get length dup 4 index gt { exit } if
  199.     4 -1 roll exch sub 3 1 roll
  200.     dup length 1 sub 1 exch getinterval
  201.       }
  202.      loop
  203.         % Stack: pos string glyphdata glyphdata[0]length
  204.         % We know no request can span more than 2 strings.
  205.      3 index 3 index length add 1 index le
  206.       {        % Request fits in a single string: just return a substring.
  207.     pop 0 get 3 1 roll length getinterval
  208.       }
  209.       {        % Request spans 2 strings.  Copy the first part.
  210.     1 index 0 get 4 index 3 -1 roll 1 index sub getinterval
  211.     2 index copy
  212.         % Copy the second part.
  213.         % Stack: pos str glyphdata str1
  214.     length exch 1 get 0 3 index length
  215.     3 index sub getinterval 2 index 3 1 roll putinterval
  216.     exch pop
  217.       }
  218.      ifelse
  219.    }
  220.   ifelse
  221. } bind def
  222.  
  223. % Interpret a byte string as a (big-endian) integer.
  224. /.cvbsi            % <bytes> .cvbsi <int>
  225. { 0 exch { exch 8 bitshift add } forall
  226. } bind def
  227.  
  228. % Read an integer from binary data.
  229. /.readint        % <pos> <nbytes> .readint <int>
  230. { string ReadString .cvbsi
  231. } bind def
  232.  
  233. % Read the glyph data for a given CID.
  234. % The CIDFont is currentdict.
  235. /.readglyphdata        % <cid> .readglyphdata <subfont> <string|null>
  236. { currentdict /GlyphDirectory .knownget
  237.    { dup type /arraytype eq
  238.       { 1 index exch get }
  239.       { 1 index exch .knownget not { null } if }
  240.      ifelse
  241.      dup null eq
  242.       { FDepVector 0 get exch }
  243.       { FDBytes 0 eq
  244.      { FDepVector 0 get exch }
  245.      {        % Note: FDBytes > 1 is not supported.
  246.        dup 0 get FDepVector exch get
  247.        exch dup length 1 sub 1 exch getinterval
  248.      }
  249.     ifelse
  250.       }
  251.      ifelse
  252.    }
  253.    { FDBytes GDBytes add mul CIDMapOffset add
  254.      dup FDBytes .readint exch
  255.      FDBytes add dup GDBytes .readint
  256.      exch GDBytes add FDBytes add GDBytes .readint
  257.             % Stack: fd pos nextpos
  258.      1 index sub dup 0 eq
  259.       { pop pop pop FDepVector 0 get null }
  260.       { string ReadString exch FDepVector exch get exch }
  261.      ifelse  
  262.    }
  263.   ifelse
  264. } bind def
  265.  
  266. % ------ CIDFontType 0 ------ %
  267.  
  268. % Read some Subrs for the current Type 1 subfont.
  269. % The subfont's Private dict is currentdict; the CIDFont itself is the
  270. % next dictionary on the stack.
  271. /.readsubrs    % <Subrs> <start> .readsubrs <Subrs>
  272. { 1 SubrCount 1 sub
  273.    { dup SDBytes mul SubrMapOffset add
  274.      dup SDBytes .readint exch SDBytes add SDBytes .readint
  275.      1 index sub string ReadString 2 index 3 1 roll put
  276.    }
  277.   for
  278. } bind def
  279.  
  280. % Ensure that all the Subrs for the current Type 1 subfont are loaded.
  281. % The subfont's Private dict is currentdict; the CIDFont itself is the
  282. % next dictionary on the stack.
  283. /.loadsubrs
  284. { currentdict /SubrMapOffset .knownget
  285.    { Subrs 0 get null ne
  286.       { pop        % We've already loaded the Subrs.
  287.       }
  288.       { SubrCache 1 index .knownget
  289.      {        % We've already loaded some Subrs at this offset.
  290.             % Make sure we've got as many as we need.
  291.        dup length SubrCount lt
  292.         {        % We need to load more.
  293.           SubrCount array exch 1 index copy length .readsubrs
  294.           SubrCache 3 -1 roll 2 index put
  295.         }
  296.        if
  297.      }
  298.      {        % We haven't loaded any Subrs at this offset yet.
  299.        SubrCount array 0 .readsubrs
  300.        SubrCache 3 -1 roll 2 index put
  301.      }
  302.     ifelse
  303.     Subrs copy pop
  304.       }
  305.      ifelse
  306.    }
  307.   if
  308. } bind def
  309.  
  310. % BuildGlyph procedure for CIDFontType 0.
  311. % ****** WHY NOT USE .type1execchar FOR THIS? ******
  312. % The name %Type9BuildGlyph is known to the interpreter.
  313. /.cid0buildstring 10 string def
  314. (%Type9BuildGlyph) cvn        % <cidfont> <cid> %Type9BuildGlyph -
  315. { .currentglobal 3 1 roll 1 index gcheck .setglobal
  316.   1 index begin
  317.   dup .readglyphdata dup null eq
  318.    { %**** HANDLE NOTDEF ****
  319.    }
  320.   if
  321.             % Stack: cidfont cid subfont charstring
  322. dup null eq { pop pop pop pop } {    %**** WRONG ****
  323.   4 -1 roll pop
  324.   exch dup /Private get begin .loadsubrs end
  325.   3 -1 roll //.cid0buildstring cvs cvn 3 1 roll
  326.   dup /CharStrings get 3 index 4 -1 roll put
  327.   setfont
  328.   1000 0 setcharwidth    %**** WRONG ****
  329.   0 0 moveto glyphshow
  330. } ifelse    %**** WRONG ****
  331.   end
  332.   .setglobal
  333. } bind def
  334.  
  335. % ------ CIDFontType 2 ------ %
  336.  
  337. % BuildGlyph procedure for CIDFontType 2.
  338. % ****** ADD THE OUTLINE STRING AS AN ARGUMENT TO .type42execchar. ******
  339. % The name %Type11BuildGlyph is known to the interpreter.
  340. (%Type11BuildGlyph) cvn        % <cidfont> <cid> %Type11BuildGlyph -
  341. { .currentglobal 3 1 roll 1 index gcheck .setglobal
  342.   1 index begin
  343.   dup GDBytes mul GDBytes string CIDMap .stringsreadstring .cvbsi
  344.             % Stack: cidfont cid glyphindex
  345. %**************** GlyphDirectory is not supported yet.
  346. (
  347.   currentdict /GlyphDirectory .knownget
  348. ) pop false
  349.    { dup type /arraytype eq
  350.       { 1 index exch get }
  351.       { 1 index exch .knownget not { null } if }
  352.      ifelse
  353.      dup null eq
  354.       { %**** HANDLE NOTDEF
  355.       }
  356.      if
  357.      1 index exch .type42execchar
  358.    }
  359.    { 1 index exch .type42execchar
  360.    }
  361.   ifelse
  362.   end
  363.   .setglobal
  364. } bind def
  365.  
  366. % ---------------- Define resources ---------------- %
  367.  
  368. languagelevel exch 2 .setlanguagelevel
  369.  
  370. % Define the CIDInit ProcSet resource.
  371. % The ProcSet dictionary is still on the stack.
  372.  
  373. /CMap /Generic /Category findresource dup length dict .copydict
  374. /Category defineresource pop
  375.     % We might have loaded CMap support already.
  376. /CIDInit /ProcSet 2 copy resourcestatus {
  377.   pop pop findresource dup length 4 index length add dict .copydict
  378.   4 -1 roll exch .copydict
  379. } {
  380.   3 -1 roll
  381. } ifelse exch defineresource pop
  382.  
  383. % Define the CIDFont resource category.
  384.  
  385. /CIDFont /Generic /Category findresource dup length dict .copydict
  386. dup /InstanceType /dicttype put
  387. dup /DefineResource {
  388.   dup /CIDFontType get dup 9 add /FontType exch 3 index 3 1 roll put
  389.   //.definecidfont exch get exec
  390.   /Generic /Category findresource /DefineResource get exec
  391. } put
  392. /Category defineresource pop
  393.  
  394. currentdict /.definecidfont undef
  395.  
  396. % Add the new FontType resources.
  397.  
  398. 9 1 11 { dup /FontType defineresource pop } for
  399.  
  400. % Add the new FMapType resource.
  401.  
  402. 9 dup /FMapType defineresource pop
  403.  
  404. % Define the CIDMap resource category.
  405. % These aren't documented, but it's clear what they are for:
  406. % to give names to CIDMaps for CIDFontType 2 fonts.
  407.  
  408. /CIDMap /Generic /Category findresource dup length dict .copydict
  409. dup /.CheckResource {
  410.     % Allow either a string or an array of strings.
  411.   dup type dup /stringtype eq
  412.    { pop true
  413.    }
  414.    { dup /arraytype eq exch /packedarraytype eq or
  415.       { true exch { type /stringtype ne { pop false exit } if } forall
  416.       }
  417.       { false
  418.       }
  419.      ifelse
  420.    }
  421.   ifelse
  422. } bind put
  423. /Category defineresource pop
  424.  
  425. .setlanguagelevel
  426.